class DuoVDOM {
  /* 检查一个标签是单标签还是双标签 */
  checkTagType(_tagNameStr) {
      return ['base',
          'br',
          'hr',
          'img',
          'input',
          'col',
          'frame',
          'link',
          'img',
          'param',
          'embed',
          'keygen',
          'area'].includes(_tagNameStr);
  }

  /* 把两个空格转换为一个空格 */
  DuoReplaceDoubelSpace(_str='') {
      return _str.trim().replace("  ", " ");
  }

  /* 移除HTML注释 */
  DuoRemoveAnnotation(_str='') {
      return _str.replace(/<\!\-\-.*\-\->/gi, "");
  }

  /* DuoVDOMTree生成器 */
  DuoVDOMTree(_TagStr) {
      let tempArr = this.DuoRemoveAnnotation(_TagStr).split(""); // 分割成单个字符串
      let tempStr = '';
      let finnalVDOMTree = [];
      let tempTagName = '';
      let matchMode = 0; // 匹配模式 0. 字符串 1. 标签名 2. 标签属性 3. innnerHTML
      let finnalTempAttributes = [];
      let that = this;
      tempArr.forEach(_item => {
          tempStr += _item;
    
          switch (matchMode) {
              case 0: handerStr(); break;
              case 1: handerTagName(); break;
              case 2: handerTagAttributes(); break;
              case 3: handerTagInnerHTML(); break;
          }


          function handerStr() {
              if (_item === '<' && tempStr.length >= 1) {
                  tempStr.slice(0, -1) && finnalVDOMTree.push({ DuoStr: tempStr.slice(0, -1) });
                  matchMode = 1;
                  tempStr = '';
              }
          }

          function handerTagName() {
              if (/\s|>|\//.test(_item)) {
                  tempTagName = tempStr.slice(0, -1);
                  if (_item === ' ') { // 如果存在属性
                      matchMode = 2;
                      tempStr = ''
                  } else {
                      
                      if (that.checkTagType(tempTagName)) {
                          /* 如果是单标签没有属性就存储单标签信息 */
                          finnalVDOMTree.push({ DuoTag: tempTagName });
                          /* 跳转到字符串匹配模式 */
                          matchMode = 0;
                      } else {
                          /* 跳转到匹配属性模式 */
                          matchMode = 3;
                      }
                      tempStr = ''; // 清空存储信息
                  }
              }
          }

          function handerTagAttributes() {
              if (/\/|>/.test(_item)) {
                  let tempAttributes = that.DuoReplaceDoubelSpace(tempStr.trim().slice(0, -1));
                  let tempAtrs = tempAttributes.split(" ");
                  tempAtrs.forEach(_atrsItem => {
                      let tempCurrentAttr = _atrsItem.split("=");
                      finnalTempAttributes.push({
                          __duoKey: tempCurrentAttr[0],
                          __duoVal: tempCurrentAttr[1].replace(/"|'/g,'') || null
                      })
                  })
                  if (that.checkTagType(tempTagName)) {
                      /* 如果是单标签就存储这个单标签 */
                      finnalVDOMTree.push({ DuoTag: tempTagName, DuoAttributes: finnalTempAttributes });
                      /* 跳转到字符串匹配模式 */
                      matchMode = 0;
                      tempStr = ''; // 清空存储信息
                  } else {
                      /* 跳转到innerHTML匹配模式 */
                      matchMode = 3;
                  }

              }


          }



          function handerTagInnerHTML() {
              let passTimes = 0;

              if ((new RegExp(`<${tempTagName}.*>`)).test(tempStr)) {
                  passTimes++;
              }

              if (tempStr.match(new RegExp(`<\/${tempTagName}>`, 'gi')) && tempStr.match(new RegExp(`<\/${tempTagName}>`, 'gi')).length - passTimes === 1) {
                  let innnerHTML = tempStr.slice(0, `</${tempTagName}>`.length * -1);
                  finnalVDOMTree.push({
                      DuoTag: tempTagName,
                      DuoAttributes: finnalTempAttributes,
                      DuoInnerHTML: innnerHTML.length > 0 ? innnerHTML : null,
                      DuoChildren: /<.+>/.test(tempStr) ? that.DuoVDOMTree(innnerHTML) : null
                  });
                  matchMode = 0;
                  tempStr = '';
              }
          }
      })
      return finnalVDOMTree;
  }



}